package com.xjy.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.xjy.common.exception.CustomException;
import com.xjy.common.exception.UtilException;
import com.xjy.common.utils.PageUtils;
import com.xjy.common.core.page.PagePlus;
import com.xjy.common.core.page.TableDataInfo;
import com.xjy.system.domain.bo.*;
import com.xjy.system.domain.vo.*;
import com.xjy.system.mapper.SysProjMapper;
import com.xjy.system.service.ISysFundaccountService;
import com.xjy.system.service.ISysProjService;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xjy.common.core.mybatisplus.core.ServicePlusImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjy.system.domain.SysCheckaccount;
import com.xjy.system.mapper.SysCheckaccountMapper;
import com.xjy.system.service.ISysCheckaccountService;

import java.util.*;

/**
 * 账户结账管理信息Service业务层处理
 *
 * @author xjy
 * @date 2022-03-18
 */
@Service
public class SysCheckaccountServiceImpl extends ServicePlusImpl<SysCheckaccountMapper, SysCheckaccount> implements ISysCheckaccountService {
	@Autowired
	private ISysProjService iSysProjService;

	@Autowired
	private SysProjMapper sysProjMapper;


	@Autowired
	private ISysFundaccountService iSysFundaccountService;


	@Override
	public SysCheckaccountVo queryById(Long id) {
		return getVoById(id, SysCheckaccountVo.class);
	}

	@Override
	public TableDataInfo<SysCheckaccountVo> queryPageList(SysCheckaccountQueryBo bo) {
		PagePlus<SysCheckaccount, SysCheckaccountVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), SysCheckaccountVo.class);
		return PageUtils.buildDataInfo(result);
	}

	@Override
	public List<SysCheckaccountVo> queryList(SysCheckaccountQueryBo bo) {
		return listVo(buildQueryWrapper(bo), SysCheckaccountVo.class);
	}

	private LambdaQueryWrapper<SysCheckaccount> buildQueryWrapper(SysCheckaccountQueryBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<SysCheckaccount> lqw = Wrappers.lambdaQuery();
		lqw.eq(bo.getProjId() != null, SysCheckaccount::getProjId, bo.getProjId());
		lqw.like(StrUtil.isNotBlank(bo.getProjName()), SysCheckaccount::getProjName, bo.getProjName());
		lqw.eq(bo.getCheckbeginDate() != null, SysCheckaccount::getCheckbeginDate, bo.getCheckbeginDate());
		lqw.eq(bo.getCheckendDate() != null, SysCheckaccount::getCheckendDate, bo.getCheckendDate());
		lqw.eq(bo.getCheckccountDate() != null, SysCheckaccount::getCheckccountDate, bo.getCheckccountDate());
		lqw.eq(bo.getChecktype() != null, SysCheckaccount::getChecktype, bo.getChecktype());
		lqw.eq(StrUtil.isNotBlank(bo.getManager()), SysCheckaccount::getManager, bo.getManager());
		lqw.eq(bo.getManagerId() != null, SysCheckaccount::getManagerId, bo.getManagerId());
		lqw.eq(StrUtil.isNotBlank(bo.getRemarks()), SysCheckaccount::getRemarks, bo.getRemarks());

		return lqw;
	}

	@Override
	public List<SysFundaccountVo> insertByAddBo(SysCheckaccountPlungeBo bo) {
		List<SysFundaccountVo> rsp = new ArrayList<>();
		bo.setProjName(iSysProjService.queryById(bo.getProjId()).getName());
		SysCheckaccount add = BeanUtil.toBean(bo, SysCheckaccount.class);
		validEntityBeforeSave(add);
		Long checktype = bo.getChecktype();
		//0：结账，1：未结账
		if(0 == checktype){
			rsp = this.plunge(bo);
		}

		save(add);
		return rsp;
	}

	@Override
	public List<SysFundaccountVo> updateByEditBo(SysCheckaccountPlungeBo bo) {
		List<SysFundaccountVo> rsp = new ArrayList<>();
		SysCheckaccount update = BeanUtil.toBean(bo, SysCheckaccount.class);
		validEntityBeforeSave(update);
		Long checktype = bo.getChecktype();
		//0：结账，1：未结账
		if(0 == checktype){
			rsp = this.plunge(bo);
		}
		updateById(update);
		return rsp;

	}

	/**
	 * 保存前的数据校验
	 *
	 * @param entity 实体类数据
	 */
	private void validEntityBeforeSave(SysCheckaccount entity) {
		//TODO 做一些数据校验,如唯一约束

	}

	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			//TODO 做一些业务上的校验,判断是否需要校验
		}
		return removeByIds(ids);
	}

	@Override
	public void check(Long projId,Date date) {
		if(null == projId || null == date){
				throw new CustomException("检测扎帐时入参不能为空！");
		}
		SysCheckaccountNextVo sysCheckaccountNextVo = this.baseMapper.queryCheckaccountNext(projId);
		if(null == sysCheckaccountNextVo){
			SysProjCheckaccountCurrentVo sysProjCheckaccountCurrentVo =	this.sysProjMapper.queryCheckaccountCurrent(projId);
			if(null == sysProjCheckaccountCurrentVo){
				throw new CustomException("查询结账信息时，未查询到项目信息！"+projId);
			}
			Date currmonthbegin = sysProjCheckaccountCurrentVo.getCurrmonthbegin();
			Date currmonthend = sysProjCheckaccountCurrentVo.getCurrmonthend();
			if(!(currmonthbegin.compareTo(date) <= 0 && currmonthend.compareTo(date) >=0)){
				throw new CustomException("扎帐期间，无法进行财务相关业务,["+currmonthbegin+"]["+currmonthend+"]");
			}

		}else {
			Date nextmonthbegin = sysCheckaccountNextVo.getNextmonthbegin();
			Date nextmonthend = sysCheckaccountNextVo.getNextmonthend();
			if(!(nextmonthbegin.compareTo(date) <= 0 && nextmonthend.compareTo(date) >=0)){
				throw new CustomException("扎帐期间，无法进行财务相关业务,["+nextmonthbegin+"]["+nextmonthend+"]");
			}

		}

	}

	@Override
	public List<SysFundaccountVo> plunge(SysCheckaccountPlungeBo bo) {
		List<SysFundaccountVo> rsp = new ArrayList<>();
		Long projId = bo.getProjId();
		if(null == projId){
			throw new CustomException("扎帐时，入参项目ID不能为空！");
		}
		Date checkbeginDate = bo.getCheckbeginDate();
		if(null == checkbeginDate){
			throw new CustomException("扎帐时，入参扎帐时间起点不能为空！");
		}
		Date checkendDate = bo.getCheckendDate();
		if(null == checkendDate){
			throw new CustomException("扎帐时，入参扎帐时间终点不能为空！");
		}
		SysFundaccountQueryBo sysFundaccountQueryBo = new SysFundaccountQueryBo();
		sysFundaccountQueryBo.setAuditStatus(true);
		sysFundaccountQueryBo.setProjId(projId);

		SysCheckaccountNextVo sysCheckaccountNextVo = this.baseMapper.queryCheckaccountNext(projId);

		if(null == sysCheckaccountNextVo){
			SysProjCheckaccountCurrentVo sysProjCheckaccountCurrentVo =	this.sysProjMapper.queryCheckaccountCurrent(projId);
			if(null == sysProjCheckaccountCurrentVo){
				throw new CustomException("扎帐时，未查询到项目信息！"+projId);
			}
			Date currmonth = sysProjCheckaccountCurrentVo.getCurrmonth();
			Date currmonthbegin = sysProjCheckaccountCurrentVo.getCurrmonthbegin();
			Date currmonthend = sysProjCheckaccountCurrentVo.getCurrmonthend();
			if(currmonth.compareTo(checkbeginDate) == 0 && currmonthend.compareTo(checkendDate) == 0){
				//TODO  验证财务日常报销情况
				this.valiBusiIsAllAudit(projId);
				rsp = iSysFundaccountService.queryList(sysFundaccountQueryBo);

			}else {
				throw new UtilException("已结账；不允许录入"+DateUtil.format(checkbeginDate,"MM")+"月份的数据");

			}

		}else {
			Date nextmonthbegin = sysCheckaccountNextVo.getNextmonthbegin();
			Date nextmonthend = sysCheckaccountNextVo.getNextmonthend();

			//当前结账日期与数据库查询到的下一个扎帐日期对比
			if(nextmonthbegin.compareTo(checkbeginDate) == 0 && nextmonthend.compareTo(checkendDate) == 0){
				//TODO  验证财务日常报销情况
				this.valiBusiIsAllAudit(projId);
				rsp = iSysFundaccountService.queryList(sysFundaccountQueryBo);

			}else {
				throw new UtilException("已结账；不允许录入"+DateUtil.format(checkbeginDate,"MM")+"月份的数据");
			}


		}


		return rsp;
	}



	private void valiBusiIsAllAudit(Long projId){
		SysBaseCheckaccountRspVo sysBaseCheckaccountRspVo = new SysBaseCheckaccountRspVo();
		sysBaseCheckaccountRspVo = baseMapper.checkDeposit(projId);
		String remark = "";
		if(null != sysBaseCheckaccountRspVo && sysBaseCheckaccountRspVo.getNotauditcount() > 0){
			remark += sysBaseCheckaccountRspVo.getRemark()+"\r\n";
//			throw new CustomException(sysBaseCheckaccountRspVo.getRemark());
		}

		sysBaseCheckaccountRspVo = baseMapper.checkCreditAdvance(projId);
		if(null != sysBaseCheckaccountRspVo && sysBaseCheckaccountRspVo.getNotauditcount() > 0){
			remark += sysBaseCheckaccountRspVo.getRemark()+"\r\n";
//			throw new CustomException(sysBaseCheckaccountRspVo.getRemark());
		}

		sysBaseCheckaccountRspVo = baseMapper.checkLoan(projId);
		if(null != sysBaseCheckaccountRspVo && sysBaseCheckaccountRspVo.getNotauditcount() > 0){
			remark += sysBaseCheckaccountRspVo.getRemark()+"\r\n";
//			throw new CustomException(sysBaseCheckaccountRspVo.getRemark());
		}

		sysBaseCheckaccountRspVo = baseMapper.checkReimbursement(projId);
		if(null != sysBaseCheckaccountRspVo && sysBaseCheckaccountRspVo.getNotauditcount() > 0){
			remark += sysBaseCheckaccountRspVo.getRemark()+"\r\n";
//			throw new CustomException(sysBaseCheckaccountRspVo.getRemark());
		}

		sysBaseCheckaccountRspVo = baseMapper.checkColpaydec(projId);
		if(null != sysBaseCheckaccountRspVo && sysBaseCheckaccountRspVo.getNotauditcount() > 0){
			remark += sysBaseCheckaccountRspVo.getRemark()+"\r\n";
//			throw new CustomException(sysBaseCheckaccountRspVo.getRemark());
		}

		if(StringUtils.isNotBlank(remark)){
			throw new CustomException(remark);

		}


	}
}
